package com.jerei.utils;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UtilsCommon {

    public static void println(Throwable throwable) {
        throwable.printStackTrace();
    }

    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append("_");
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public static String camelName(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty()) {
            // 没必要转换
            return "";
        } else if (!name.contains("_")) {
            // 不含下划线，仅将首字母小写
            return name.substring(0, 1).toLowerCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String camels[] = name.split("_");
        for (String camel : camels) {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty()) {
                continue;
            }
            // 处理真正的驼峰片段
            if (result.length() == 0) {
                // 第一个驼峰片段，全部字母都小写
                result.append(camel.toLowerCase());
            } else {
                // 其他的驼峰片段，首字母大写
                result.append(camel.substring(0, 1).toUpperCase());
                result.append(camel.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    public static String createRadom(int iLen, int iType) {
        String strRandom = " ";// 随机字符串
        Random rnd = new Random();
        if (iLen < 0) {
            iLen = 5;
        }
        if ((iType > 2) || (iType < 0)) {
            iType = 2;
        }
        switch (iType) {
            case 0:
                for (int iLoop = 0; iLoop < iLen; iLoop++) {
                    strRandom += Integer.toString(rnd.nextInt(10));
                }
                break;
            case 1:
                for (int iLoop = 0; iLoop < iLen; iLoop++) {
                    strRandom += Integer.toString((35 - rnd.nextInt(10)), 36);
                }
                break;
            case 2:
                for (int iLoop = 0; iLoop < iLen; iLoop++) {
                    strRandom += Integer.toString(rnd.nextInt(36), 36);
                }
                break;
        }
        return strRandom.trim();
    }


    public static String getPinYin(String strs) {
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
        char[] ch = strs.trim().toCharArray();
        StringBuffer buffer = new StringBuffer("");
        try {
            for (int i = 0; i < ch.length; i++) {
                // unicode，bytes应该也可以.
                if (Character.toString(ch[i]).matches("[\u4e00-\u9fa5]+")) {
                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(ch[i], format);
                    buffer.append(temp[0]);// :结果"?"已经查出，但是音调是3声时不显示myeclipse8.6和eclipse
                    buffer.append(" ");
                } else {
                    buffer.append(Character.toString(ch[i]));
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }
        String str = buffer.toString().trim();
        str = str.replaceAll(" ", "-");
        return str;
    }


    public static void println(String str) {
        System.out.println(str);
    }

    public static void println(Object object) {
        System.out.println(object);
    }

    public static String getStackTraceElement(Throwable throwable) {
        StringBuffer stringBuffer = new StringBuffer();
        StackTraceElement[] ste = throwable.getStackTrace();
        for (int i = 0; i < ste.length; i++) {
            stringBuffer.append(ste[i].toString() + "<br />\r\n");
        }
        return stringBuffer.toString();
    }


    public static String getSmallImg(String img, String folder) {
        if (null == img || img.indexOf("/") < 0) {
            return "";
        }
        img = img.substring(0, img.lastIndexOf("/") + 1) + folder + img.substring(img.lastIndexOf("/"));
        return img;
    }


    public static String securityFilter(String str) {
        if (null != str) {
            str = str.replace("00:00:00.0", "").replace(":00.0", "").replace("'", "").replace("\"", "").replaceAll("\\b[sS][cC][rR][iI][pP][tT]\\b", "").replaceAll(
                    "\\b[aA][nN][dD]\\b ", "").replaceAll("\\b[oO][rR]\\b ", "").replace("--", "").replaceAll("\\b[iI][fF][rR][aA][mM][eE]\\b", "").replaceAll(".*([';]+|(--)+).*",
                    " ").trim();
        }
        return str;
    }

    private static String filterXSS(String value) {
        if (value == null || value.length() == 0) {
            return value;
        }

        StringBuffer result = null;
        String filtered = null;
        for (int i = 0; i < value.length(); i++) {
            filtered = null;
            switch (value.charAt(i)) {
                case '<':
                    filtered = "<";
                    break;
                case '>':
                    filtered = ">";
                    break;
                case '&':
                    filtered = "&";
                    break;
                case '"':
                    filtered = "\"";
                    break;
                case '\'':
                    filtered = "'";
                    break;
            }

            if (result == null) {
                if (filtered != null) {
                    result = new StringBuffer(value.length() + 50);
                    if (i > 0) {
                        result.append(value.substring(0, i));
                    }
                    result.append(filtered);
                }
            } else {
                if (filtered == null) {
                    result.append(value.charAt(i));
                } else {
                    result.append(filtered);
                }
            }
        }
        return result == null ? value : result.toString();
    }

    private static boolean sqlValidate(String str) {
        if (null == str) {
            str = "";
        }
        str = str.toLowerCase();// 统一转为小写
        String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|"
                + "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" + "table|from|grant|use|group_concat|column_name|"
                + "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" + "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";// 过滤掉的sql关键字，可以手动添加
        String[] badStrs = badStr.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) >= 0) {
                return true;
            }
        }
        return false;
    }

    public static String[] getPicFromContent(String str) {
        if (str == null || str.length() == 0) {
            return null;
        }
        String returnStr = "";
        Matcher m = Pattern.compile("src=\"?(.*?)(\"|>|\\s+)", Pattern.CASE_INSENSITIVE).matcher(str);
        while (m.find()) {
            if (m.group(1).indexOf(".gif") == -1 && m.group(1).indexOf(".GIF") == -1 && m.group(1).indexOf(".JPG") == -1 && m.group(1).indexOf(".jpg") == -1
                    && m.group(1).indexOf(".PNG") == -1 && m.group(1).indexOf(".png") == -1 && m.group(1).indexOf(".BMP") == -1 && m.group(1).indexOf(".bmp") == -1) {
                continue;
            }
            if (m.group(1) == null || m.group(1).equals("")) {
                continue;
            }
            returnStr += m.group(1).replace("'", "").replace("\"", "") + ",";
        }
        if (null == returnStr || "".equals(returnStr)) {
            return new String[]{};
        }
        return returnStr.split(",");
    }

    public static String getOnePicFromContent(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }
        String returnStr = "";
        int n = 1;
        Matcher m = Pattern.compile("src=\"?(.*?)(\"|>|\\s+)", Pattern.CASE_INSENSITIVE).matcher(str);
        while (m.find()) {
            if (m.group(1).indexOf(".png") == -1 && m.group(1).indexOf(".PNG") == -1 && m.group(1).indexOf(".gif") == -1 && m.group(1).indexOf(".GIF") == -1
                    && m.group(1).indexOf(".JPG") == -1 && m.group(1).indexOf(".jpg") == -1) {
                continue;
            }
            if (n == 2) {
                break;
            }
            returnStr += m.group(1).replace("'", "").replace("\"", "") + ",";
            n = 2;
        }
        if (null != returnStr && returnStr.indexOf(",") != -1) {
            returnStr = returnStr.replace(",", "");
        }
        return returnStr;
    }

    public static String substringByte(String str, int length) {
        return substring(str, 0, length);
    }

    public static String substringByte(String str, int length, String endStr) {
        if (null == str) {
            return "";
        }
        String tempStr = substringByte(str, length);
        if (tempStr.length() < str.length()) {
            str = tempStr + endStr;
        }
        return str;
    }


    public static String substringByte(String str, int length, Boolean isFilterHtml) {
        if (null == str) {
            return "";
        }
        if (isFilterHtml) {
            str = filterHtml(str);
        }
        str = substringByte(str, length);
        return str;
    }

    public static String getUUID() {
        return UUID.randomUUID().toString();
    }

    public static String substring(String origin, int begin, int end, String appendStr, String encoding) {
        if (origin == null || origin.equals("")) {
            return appendStr;
        }
        if (begin < 0) {
            begin = 0;
        }
        if (end < 0) {
            return "";
        }
        if (begin > end) {
            return "";
        }
        if (begin == end) {
            return "";
        }
        if (begin > length(origin)) {
            return "";
        }
        if (end > length(origin)) {
            end = length(origin) - 1;
        }
        if (null != encoding && !"".equals(encoding)) {
            encoding = "UTF-8";
        }
        int len = end - begin;
        byte[] strByte = new byte[len];
        try {
            System.arraycopy(origin.getBytes(encoding), begin, strByte, 0, len);
            int count = 0;
            for (int i = 0; i < len; i++) {
                int value = (int) strByte[i];
                if (value < 0) {
                    count++;
                }
            }
            if (count % 2 != 0) {
                len = (len == 1) ? ++len : --len;
            }
            return new String(strByte, 0, len, encoding) + appendStr;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (StringIndexOutOfBoundsException ex) {
            return appendStr;
        } catch (Exception ex) {
            return "";
        }
    }

    public static boolean isLetter(char c) {
        int k = 0x80;
        return c / k == 0 ? true : false;
    }


    public static int length(String s) {
        if (s == null) {
            return 0;
        }
        char[] c = s.toCharArray();
        int len = 0;
        for (int i = 0; i < c.length; i++) {
            len++;
            // 如果为汉，日，韩，则多加一位
            if (!isLetter(c[i])) {
                len++;
            }
        }
        return len;
    }

    public static String substring(String str, int srcPos, int specialCharsLength) {
        if (str == null || "".equals(str) || specialCharsLength < 1) {
            return "";
        }
        if (srcPos < 0) {
            srcPos = 0;
        }
        if (specialCharsLength <= 0) {
            return "";
        }
        // 获得字符串的长度
        char[] chars = str.toCharArray();
        if (srcPos > chars.length) {
            return "";
        }
        int charsLength = getCharsLength(chars, specialCharsLength);
        return new String(chars, srcPos, charsLength);
    }

    private static int getCharsLength(char[] chars, int specialCharsLength) {
        int count = 0;
        int normalCharsLength = 0;
        for (int i = 0; i < chars.length; i++) {
            int specialCharLength = getSpecialCharLength(chars[i]);
            if (count <= specialCharsLength - specialCharLength) {
                count += specialCharLength;
                normalCharsLength++;
            } else {
                break;
            }
        }
        return normalCharsLength;
    }

    private static int getSpecialCharLength(char c) {
        if (isLetter(c)) {
            return 1;
        } else {
            return 2;
        }
    }


    public static String getString(Object strObj) {
        String str = "";
        if (null != strObj) {
            str = strObj.toString();
        }
        return str;
    }


    public static Integer getInteger(Object strObj) {
        String value = getString(strObj);
        if ("".equals(value)) {
            return null;
        }
        return NumberUtils.toInt(value);
    }


    public static Long getLong(Object strObj) {
        String value = getString(strObj);
        if ("".equals(value)) {
            return null;
        }
        return NumberUtils.toLong(value);
    }

    public static Double getDouble(Object strObj) {
        String value = getString(strObj);
        if ("".equals(value)) {
            return null;
        }
        return NumberUtils.toDouble(value);
    }

    public static String doubleFormat(Double d, int m) {
        String str = "0";
        if (m > 0) {
            String t = "";
            for (int i = 1; i <= m; i++) {
                t += "0";
            }
            str += "." + t;
        }
        java.text.DecimalFormat df = new java.text.DecimalFormat(str);
        return df.format(d) + "";
    }

    private static String imgGetAddFolder(File file, String folderName) {
        String pathFile = file.getAbsolutePath();
        String fPath = pathFile.substring(0, pathFile.lastIndexOf(File.separator));
        String bPath = pathFile.substring(pathFile.lastIndexOf(File.separator));
        File fPathFile = new File(fPath + File.separator + folderName);
        if (!fPathFile.exists()) {
            fPathFile.mkdir();
        }
        String path = fPath + File.separator + folderName + bPath;
        return path;
    }

    public static String imgCopyOriginalImage(File imageFile) throws IOException {
        File file = new File(imgGetAddFolder(imageFile, "l"));
        FileUtils.copyFile(imageFile, file);
        String _name = file.getAbsolutePath();
        _name = _name.substring(_name.indexOf(File.separator + "upload" + File.separator));
        _name = _name.replaceAll("\\\\", "/");
        return _name;
    }

    public static String filterHtml(String str) {
        Document document = Jsoup.parse(str);
        return document.text();
    }

    public static String encode(String str) {
        try {
            str = URLEncoder.encode(str, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return str;
    }

    public static String decode(String str) {
        try {
            str = URLDecoder.decode(str, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ;
        return str;
    }

}
